package com.jrx.anytxn.param.transaction.job.billCompare.config;

import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.TlBillTransInnerSummary;
import com.jrx.anytxn.param.mapper.ext.ExtTlBillTransInnerSummaryMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.transaction.config.BillCompareConfig;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlDisbursementLogMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;


/**
 * 核心对账-txn内部交易流水汇总job
 *
 * @author : zcc
 * 2020/11/30
 */
@Configuration
public class BillSummaryReadConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(BillSummaryReadConfiguration.class);

    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    @Resource
    private ExtTlDisbursementLogMapper extTlDisbursementLogMapper;
    @Resource
    private ExtTlBillTransInnerSummaryMapper extTlBillTransInnerSummaryMapper;
    @Autowired
    private ISegmentService iSegmentService;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Resource
    private ExtTlPaymentLogMapper extTlPaymentLogMapper;
    @Autowired
    private BillCompareConfig billCompareConfig;

    @Bean
    public Job billSummaryReadJob() {
        return jobBuilderFactory.get("billSummaryReadJob")
                .start(billSummaryForFKReadStep())
                .next(billSummaryForHKReadStep())
                .build();
    }

    @Bean
    public Step billSummaryForFKReadStep() {
        return stepBuilderFactory.get("billSummaryForFKReadStep")
                .tasklet(billSummaryForFKReadTasklet())
                .build();
    }

    @Bean
    @StepScope
    public Tasklet billSummaryForFKReadTasklet() {
        return (stepContribution, chunkContext) -> {
            PrOrganizationTable organization = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
            Date businessDate = organization.getToday();
            String busDate = DateUtils.format(businessDate);
            logger.info("核心放款对账-txn内部交易流水汇总开始。。。,业务日期{}", busDate);
            List<Map<String, Object>> resultList = new ArrayList<>();
            Integer totalCount = 0;
            BigDecimal totalAmount = BigDecimal.ZERO;
            //清除当日对账数据，支持重跑
            extTlBillTransInnerSummaryMapper.deleteByFromAndBusDate(billCompareConfig.getDataFrom(), businessDate);

            //成功笔数、金额
            totalCount = extTlDisbursementLogMapper
                    .countBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S, businessDate);
            totalAmount = extTlDisbursementLogMapper
                    .sumBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S, businessDate);
            Map<String, Object> result = new HashMap<>();
            result.put("innerStatus", TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S);
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            resultList.add(result);

            //失败笔数、金额
            totalCount = extTlDisbursementLogMapper
                    .countBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F, businessDate);
            totalAmount = extTlDisbursementLogMapper
                    .sumBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F, businessDate);
            result = new HashMap<>();
            result.put("innerStatus", TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F);
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            resultList.add(result);

            //处理中笔数、金额
            totalCount = extTlDisbursementLogMapper
                    .countBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O, businessDate);
            totalAmount = extTlDisbursementLogMapper
                    .sumBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O, businessDate);
            result = new HashMap<>();
            result.put("innerStatus", TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O);
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            resultList.add(result);

            List<TlBillTransInnerSummary> tlBillTransInnerSummaryList
                    = buildTransInnerSumList(resultList, organization, Constant.TRANS_TYPE_FK);

            if(CollectionUtils.isNotEmpty(tlBillTransInnerSummaryList)){
                extTlBillTransInnerSummaryMapper.insertbatch(tlBillTransInnerSummaryList);
            }

            logger.info("核心放款对账-txn内部交易流水汇总完成。。。,业务日期{}", busDate);
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Step billSummaryForHKReadStep() {
        return stepBuilderFactory.get("billSummaryForHKReadStep")
                .tasklet(billSummaryForHKReadTasklet())
                .build();
    }

    @Bean
    @StepScope
    public Tasklet billSummaryForHKReadTasklet() {
        return (stepContribution, chunkContext) -> {
            PrOrganizationTable organization = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
            Date businessDate = organization.getToday();
            String busDate = DateUtils.format(businessDate);

            logger.info("核心还款对账-txn内部交易流水汇总开始。。。,业务日期{}", busDate);
            List<Map<String, Object>> resultList = new ArrayList<>();
            Integer totalCount = 0;
            BigDecimal totalAmount = BigDecimal.ZERO;

            //成功笔数、金额
            totalCount = extTlPaymentLogMapper
                    .countBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S, businessDate);
            totalAmount = extTlPaymentLogMapper
                    .sumBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S, businessDate);
            Map<String, Object> result = new HashMap<>();
            result.put("innerStatus", TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S);
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            resultList.add(result);

            //失败笔数、金额
            totalCount = extTlPaymentLogMapper
                    .countBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F, businessDate);
            totalAmount = extTlPaymentLogMapper
                    .sumBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F, businessDate);
            result = new HashMap<>();
            result.put("innerStatus", TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F);
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            resultList.add(result);

            //处理中笔数、金额
            totalCount = extTlPaymentLogMapper
                    .countBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O, businessDate);
            totalAmount = extTlPaymentLogMapper
                    .sumBySumStatusAndBusinessDate(organization.getTenantId(), TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O, businessDate);
            result = new HashMap<>();
            result.put("innerStatus", TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O);
            result.put("totalCount", totalCount);
            result.put("totalAmount", totalAmount);
            resultList.add(result);
            //
            List<TlBillTransInnerSummary> tlBillTransInnerSummaryList
                    = buildTransInnerSumList(resultList, organization, Constant.TRANS_TYPE_HK);
            if(CollectionUtils.isNotEmpty(tlBillTransInnerSummaryList)){
                extTlBillTransInnerSummaryMapper.insertbatch(tlBillTransInnerSummaryList);
            }
            logger.info("核心还款对账-txn内部交易流水汇总完成。。。,业务日期{}", busDate);
            return RepeatStatus.FINISHED;
        };
    }

    private List<TlBillTransInnerSummary> buildTransInnerSumList(List<Map<String, Object>> resultList
            , PrOrganizationTable organization, String transType) throws SegmentException {
        List<TlBillTransInnerSummary> tlBillTransInnerSummaryList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(resultList)){
            for (Map<String, Object> res : resultList){
                TlBillTransInnerSummary tlBillTransInnerSummary =  new TlBillTransInnerSummary();
                tlBillTransInnerSummary.setTenantId(organization.getTenantId());
                tlBillTransInnerSummary.setOrganizationId(organization.getOrganizationId());
                tlBillTransInnerSummary.setId(iSegmentService.getId("TlBillTransInnerSummary"));
                tlBillTransInnerSummary.setBillType(transType);
                tlBillTransInnerSummary.setBusinessDate(organization.getToday());
                tlBillTransInnerSummary.setInnerStatus(String.valueOf(res.get("innerStatus")));
                tlBillTransInnerSummary.setInnerTotalCount((Integer) res.get("totalCount"));
                tlBillTransInnerSummary.setInnerTotalAmount((BigDecimal) res.get("totalAmount"));
                tlBillTransInnerSummary.setDataFrom(billCompareConfig.getDataFrom());
                tlBillTransInnerSummaryList.add(tlBillTransInnerSummary);
            }
        }
        return tlBillTransInnerSummaryList;
    }

}
